#include "kbc.h"


int kbc_init(int debug);



int write_kbc_cmd( unsigned data) 
{
	return write_kbc(CMD_REG, data);
}


  

int write_kbc_data( unsigned data)
{

	int tries = 0;
	
	
	while (tries < 3) {
	
		if (write_kbc(DATA_REG, data) == -1){
			//Error
			return -1;
		}
		
		if (read_kbc() == Resend){
		
			tries++;
			
		} else {
		
			return ACK;
		}
		
	}
	
	return Error;
}




int read_kbc(void) 
{

	int status, time = 0;
	
	//while there's no timeout, reads from keyboard controler
	while(time < KBC_TIMEOUT){
	
		//Read status
		status = inportb(STAT_REG);
		
		if ( (status & OBF) != 0 ){ //there is data to be read
					
			int data = inportb(DATA_REG);
			
			//if parity or timeout error
			if ( (data & (PAR_ERR | TO_ERR)) != 0 ){
			
				return -1;
			}
			
			//returns the keyboard data
			if ( (data & AUX) == 0){
				
				return data;
				
			} 
			
			return 0;
		}
		
		time++; //the time is incremented
		
		delay(100); //delays 100 ms
	}
	
	return -1;
}




int write_kbc(unsigned adr, unsigned data) 
{
	int status, time = 0;
	
	//while there's no timeout, writes to keyboard controler
	while (time < KBC_TIMEOUT) {
	
		//read status
		status = inportb(STAT_REG);
		
		if ( (status & IBF) == 0 ){
			
			outportb(adr, data); //writes to the outport
			
			return 1;
		}
		
		time++; //the time is incremented
		
		delay(100); //delays 100 ms
	}
	
	return -1;
}




void blink_leds(void) 
{
	write_kbc_data(WriteLEDS);
	
	write_kbc_data(SCROLL_LOCK | NUM_LOCK | CAPS_LOCK);
	
	delay(1000);
	
	write_kbc_data(WriteLEDS);
	
	write_kbc_data(0x0);
}




void blink_led(uchar led) 
{
	write_kbc_data(WriteLEDS);
	
	write_kbc_data(led);
	
	delay(500);
	
	write_kbc_data(WriteLEDS);
	
	write_kbc_data(0x0);
}




